package com.base.lib.base.view

import android.content.Context
import android.os.Bundle
import android.util.AttributeSet
import android.util.Log
import android.view.View
import androidx.lifecycle.ViewModelProvider
import com.base.lib.base.mvvm.repository.BaseRepository
import com.base.lib.base.mvvm.viewmodel.BaseViewModel
import com.base.lib.base.utils.ext.view.showToast
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.TimeoutCancellationException
import retrofit2.HttpException

/**
 * Describe:
 * 基础 MVVM 页面
 *
 */
abstract class BaseMvvmActivity<VM : BaseViewModel> : BaseActivity() {

    protected val mViewModel: VM by lazy { ViewModelProvider(this).get(onBindViewModel()) }

    override fun initCommonView() {
        super.initCommonView()
        initBaseViewObservable()
        initViewObservable()
    }

    /**
     * 绑定 ViewModel
     */
    abstract fun onBindViewModel(): Class<VM>

    /**
     * 放置 观察者对象
     */
    protected open fun initViewObservable(){}

    /**
     * 初始化页面观察 变更相应的展示
     */
    protected open fun initBaseViewObservable() {
        // 将 Activty 的生命周期同步到 ViewModel 中
        lifecycle.addObserver(mViewModel)

        mViewModel.mUIChangeLiveData.getShowToastViewEvent()
            .observe(this) { it.showToast() }
        mViewModel.mUIChangeLiveData.getShowInitLoadViewEvent()
            .observe(this) {
                showInitLoadView(it)
            }
        mViewModel.mUIChangeLiveData.getShowTransLoadingViewEvent()
            .observe(this) {
                showTransLoadingView(it)
            }
        mViewModel.mUIChangeLiveData.getShowNoDataViewEvent()
            .observe(this) {
                showNoDataView(it)
            }
        mViewModel.mUIChangeLiveData.getShowNetWorkErrViewEvent()
            .observe(this) {
                showNetWorkErrView(it)
            }
        mViewModel.mUIChangeLiveData.getStartActivityEvent()
            .observe(this) {
                val clz =
                    it[BaseViewModel.ParameterField.CLASS] as Class<*>?
                val bundle = it[BaseViewModel.ParameterField.BUNDLE] as Bundle?
                startActivity(clz, bundle)
            }
        mViewModel.mUIChangeLiveData.getFinishActivityEvent()
            .observe(this) { finish() }
        mViewModel.mUIChangeLiveData.getOnBackPressedEvent()
            .observe(this) { onBackPressed() }
    }

    override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? {
        return super.onCreateView(name, context, attrs)
        startObserve()
    }

    private fun startObserve() {
        //处理一些通用异常，比如网络超时等
        mViewModel.run {
            getError().observe(mContext, {
                requestError(it)
            })
            getFinally().observe(mContext, {
                requestFinally(it)
            })
        }
    }

    open fun requestFinally(it: Int?) {

    }

    open fun requestError(it: Exception?) {
        //处理一些已知异常
        it?.run {
            when (it) {
                is CancellationException -> Log.d("${BaseActivity.TAG}--->接口请求取消", it.message.toString())
                is TimeoutCancellationException -> "请求超时".showToast()
                is BaseRepository.TokenInvalidException -> "登陆超时".showToast()
                is HttpException -> { if (it.code() == 504) "无法连接服务器,请检查网络设置".showToast() else it.message.toString().showToast() }
                else -> it.message.toString().showToast()
            }
        }
    }

}
